<template>
  <div>
    <div>
      <el-upload
        :action="uploadUrl"
        :before-upload="handleBeforeUpload"
        :on-success="handleUploadSuccess"
        :on-error="handleUploadError"
        name="file"
        :show-file-list="false"
        :headers="headers"
        class="editor-img-uploader"
        v-if="type == 'url'"
      >
        <i ref="uploadRef" class="editor-img-uploader"></i>
      </el-upload>
    </div>
    <div class="editor">
      <quill-editor
        ref="quillEditorRef"
        v-model:content="content"
        contentType="html"
        @textChange="handleTextChange"
        @compositionstart="onCompositionStart"
        @compositionend="onCompositionEnd"
        :options="options"
        :style="styles"
      />
    </div>
  </div>
</template>

<script setup>
import { QuillEditor } from "@vueup/vue-quill";
import "@vueup/vue-quill/dist/vue-quill.snow.css";
import { getToken } from "@/utils/auth";
import {
  getCurrentInstance,
  ref,
  watch,
  onMounted,
  computed,
  defineProps,
  defineEmits,
  nextTick
} from "vue";

const instance = getCurrentInstance();
const proxy = instance ? instance.proxy : null;

const quillEditorRef = ref();
const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/upload"); // 上传的图片服务器地址
const headers = ref({
  Authorization: "Bearer " + getToken()
});
const emit = defineEmits(["update:modelValue", "update:wordCount"]);

// 标志位，用于判断是否正在进行组合输入
const isComposing = ref(false);

const props = defineProps({
  /* 编辑器的内容 */
  modelValue: {
    type: String
  },
  /* 高度 */
  height: {
    type: Number,
    default: null
  },
  /* 最小高度 */
  minHeight: {
    type: Number,
    default: null
  },
  /* 只读 */
  readOnly: {
    type: Boolean,
    default: false
  },
  /* 上传文件大小限制(MB) */
  fileSize: {
    type: Number,
    default: 20
  },
  /* 类型（base64格式、url格式） */
  type: {
    type: String,
    default: "url"
  },
  /* 字数统计 */
  wordCount: {
    type: Number,
    default: 0
  },
  // 是否禁用文本输入功能
  isDisabled: {
    type: Boolean,
    default: false
  }
});

const options = ref({
  theme: "snow",
  bounds: document.body,
  debug: "warn",
  modules: {
    // 工具栏配置
    toolbar: [
      ["bold"],
      [{ color: [] }],
      [{ background: [] }],
      [{ list: "ordered" }],
      [{ list: "bullet" }],
      ["blockquote"],
      [{ align: [] }],
      ["clean"]
      // ["link"],
      // ["video"]
      // ["image"],
    ]
  },
  placeholder: "开始写下今天的故事...",
  readOnly: props.readOnly
});

const styles = computed(() => {
  let style = {};
  if (props.minHeight) {
    style.minHeight = `${props.minHeight}px`;
  }
  if (props.height) {
    style.height = `${props.height}px`;
  }
  if (props.isDisabled) {
    style.cursor = "not-allowed";
  } else {
    style.cursor = "default";
  }
  return style;
});

const content = ref("");
const firstLoad = ref(true);

// 监听 modelValue 的变化
watch(
  () => props.modelValue,
  v => {
    if (firstLoad.value) {
      content.value = v === undefined ? "<p></p>" : v;
      nextTick(() => {
        if (quillEditorRef.value) {
          quillEditorRef.value.setHTML(content.value || "<p></p>");
        }
      });
      firstLoad.value = false;
    } else if (v !== content.value) {
      content.value = v;
      nextTick(() => {
        if (quillEditorRef.value) {
          quillEditorRef.value.setHTML(content.value || "<p></p>");
        }
      });
    }
  },
  { immediate: true }
);

// 监听 isDisabled 的变化
watch(
  () => props.isDisabled,
  newVal => {
    if (quillEditorRef.value) {
      let quill = quillEditorRef.value.getQuill();
      setQuillEnabled(quill, !newVal);
    }
  },
  { immediate: true }
);

// 如果设置了上传地址则自定义图片和视频上传事件
onMounted(() => {
  nextTick(() => {
    if (props.type == "url") {
      if (quillEditorRef.value) {
        let quill = quillEditorRef.value.getQuill();
        let toolbar = quill.getModule("toolbar");
        toolbar.addHandler("image", value => {
          if (value) {
            if (proxy) {
              proxy.$refs.uploadRef.click();
            }
          } else {
            quill.format("image", false);
          }
        });
        // toolbar.addHandler("video", value => {
        //   if (value) {
        //     proxy.$refs.uploadRef.click();
        //   } else {
        //     quill.format("video", false);
        //   }
        // });
        // 设置编辑器初始状态
        setQuillEnabled(quill, !props.isDisabled);
      }
    }
  });
});

// 辅助函数：设置 Quill 编辑器的启用状态
function setQuillEnabled(quill, enabled) {
  quill.enable(enabled);
}

// 上传前校检格式和大小
function handleBeforeUpload(file) {
  const supportedTypes = [
    "image/jpeg",
    "image/jpg",
    "image/png",
    "image/svg",
    "video/mp4",
    "video/avi",
    "video/x-rmvb"
  ];
  const isValidType = supportedTypes.includes(file.type);
  // console.log(file.type);

  // 检验文件格式
  if (!isValidType) {
    if (proxy) {
      proxy.$modal.msgError(
        `文件格式错误！仅支持 ${supportedTypes
          .map(type => type.split("/")[1])
          .join(", ")} 格式。`
      );
    }
    return false;
  }

  // 校检文件大小
  if (props.fileSize) {
    const isLt = file.size / 1024 / 1024 < props.fileSize;
    if (!isLt) {
      if (proxy) {
        proxy.$modal.msgError(`上传文件大小不能超过 ${props.fileSize} MB！`);
      }
      return false;
    }
  }

  return true;
}

// 上传成功处理
function handleUploadSuccess(res, file) {
  // 如果上传成功
  if (res.code == 200) {
    // 获取富文本实例
    if (quillEditorRef.value) {
      let quill = quillEditorRef.value.getQuill();
      // 获取光标位置
      let length = quill.selection.savedRange.index;
      // 获取文件类型，通过file.raw.type，而不是file.type。打印file对象查看即可
      const fileType = file.raw ? file.raw.type : undefined;

      if (fileType.startsWith("image")) {
        // 插入图片
        quill.insertEmbed(
          length,
          "image",
          import.meta.env.VITE_APP_BASE_API + res.fileName
        );
      } else if (fileType.startsWith("video")) {
        // 插入视频
        quill.insertEmbed(
          length,
          "video",
          import.meta.env.VITE_APP_BASE_API + res.fileName
        );
      }

      // 调整光标到最后
      quill.setSelection(length + 1);
    }
  } else {
    if (proxy) {
      proxy.$modal.msgError("文件插入失败");
    }
  }
}

// 上传失败处理
function handleUploadError() {
  if (proxy) {
    proxy.$modal.msgError("文件插入失败");
  }
}

// 处理组合输入开始事件
const onCompositionStart = () => {
  isComposing.value = true;
};

// 处理组合输入结束事件
const onCompositionEnd = () => {
  isComposing.value = false;
  // 组合输入结束后，进行字数统计
  const wordCount = calculateWordCount(content.value);
  // console.log(wordCount);
  emit("update:wordCount", wordCount);
};

// 计算字数
function calculateWordCount(htmlString) {
  const tempDiv = document.createElement("div");
  tempDiv.innerHTML = htmlString;
  // 获取去除 HTML 标签后的纯文本内容
  const textContent = tempDiv.textContent;
  // 检查 textContent 是否为空或仅包含空白字符
  if (!textContent || textContent.trim().length === 0) {
    return 0;
  }
  // 返回文本内容的长度
  return textContent.trim().length;
}

// 处理内容变化
function handleTextChange() {
  emit("update:modelValue", content.value);
  // isComposing.value 为 true 时，表示正在输入中文，不进行字数统计，否则进行字数统计
  if (!isComposing.value) {
    const wordCount = calculateWordCount(content.value);
    // console.log(wordCount);
    emit("update:wordCount", wordCount);
  }
}
</script>

<style>
.editor-img-uploader {
  display: none;
}
.editor,
.ql-toolbar {
  white-space: pre-wrap !important;
  line-height: normal !important;
}
.quill-img {
  display: none;
}
.ql-snow .ql-tooltip[data-mode="link"]::before {
  content: "请输入链接地址:";
}
.ql-snow .ql-tooltip.ql-editing a.ql-action::after {
  border-right: 0px;
  content: "保存";
  padding-right: 0px;
}
.ql-snow .ql-tooltip[data-mode="video"]::before {
  content: "请输入视频地址:";
}
.ql-snow .ql-picker.ql-size .ql-picker-label::before,
.ql-snow .ql-picker.ql-size .ql-picker-item::before {
  content: "14px";
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before {
  content: "10px";
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before {
  content: "18px";
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before {
  content: "32px";
}
.ql-snow .ql-picker.ql-header .ql-picker-label::before,
.ql-snow .ql-picker.ql-header .ql-picker-item::before {
  content: "文本";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
  content: "标题1";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
  content: "标题2";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
  content: "标题3";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
  content: "标题4";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
  content: "标题5";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
  content: "标题6";
}
.ql-snow .ql-picker.ql-font .ql-picker-label::before,
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
  content: "标准字体";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="serif"]::before {
  content: "衬线字体";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before {
  content: "等宽字体";
}
/* 控制编辑器禁用 */
/* .disabled-editor {
  pointer-events: none;
} */
</style>ssss
